using System.BusinessObjects.Providers;
using System.Collections;
using System.Data;
using System.Reflection;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Tool.hbm2ddl;
using Blazing.BusinessObjects.Cms;
using System.Collections.Generic;
using System.BusinessObjects.Transactions;

using NUnit.Framework;
using TestClass = NUnit.Framework.TestFixtureAttribute;
using TestMethod = NUnit.Framework.TestAttribute;
using TestInitialize = NUnit.Framework.SetUpAttribute;
using TestCleanup = NUnit.Framework.TearDownAttribute;
using ClassInitialize = NUnit.Framework.TestFixtureSetUpAttribute;
using ClassCleanup = NUnit.Framework.TestFixtureTearDownAttribute;
using Blazing.BusinessObjects.Products;


namespace BusinessObjectTests
{
    /// <summary>
    /// Provides a fixture base for Unit tests to be run on an In-Memory SQLite db
    /// </summary>
    [TestClass]
    public class NHibernateInMemoryTestFixtureBase
    {
        protected static ISessionFactory sessionFactory;
        protected static Configuration configuration;
        protected ISession session;

        private List<Assembly> _Assemblies = new List<Assembly>();
        public List<Assembly> Assemblies
        {
            get
            {
                if (_Assemblies.Count == 0)
                {
                    _Assemblies.Add(typeof(Site).Assembly);
                    _Assemblies.Add(typeof(Product).Assembly);
                }
                return _Assemblies;
            }
        }

        [TestInitialize]
        public void Setup()
        {
            OneTimeInitalize(Assemblies.ToArray());
            NHibernateSessionProvider.CurrentFactory = sessionFactory;
            session = CreateSession();
            NHibernateSessionProvider.Provider.CurrentSession = session;
            UnitOfWork.CurrentSession.BeginTransaction();
        }

        [TestCleanup]
        public void TearDown()
        {
            if (UnitOfWork.CurrentSession.Transaction.IsActive)
                UnitOfWork.CurrentSession.Transaction.Rollback();
        }

        [TestCleanup]
        public void FixtureTearDown()
        {
            if(session != null)
                session.Dispose();
            session = null;
            //sessionFactory.Dispose();
        }

        

        /// <summary> 
        /// Initialize NHibernate and builds a session factory 
        /// Note, this is a costly call so it will be executed only one. 
        /// </summary> 
        public static void OneTimeInitalize(params Assembly[] assemblies)
        {
            if (sessionFactory != null)
                return;
            Dictionary<string, string> properties = new Dictionary<string, string>();
            properties.Add("connection.driver_class", "NHibernate.Driver.SQLite20Driver");
            properties.Add("dialect", "NHibernate.Dialect.SQLiteDialect");
            properties.Add("show_sql", "true");
            properties.Add("connection.provider", "NHibernate.Connection.DriverConnectionProvider");
            properties.Add("proxyfactory.factory_class", "NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle");
            properties.Add("connection.connection_string", "Data Source=:memory:;Version=3;New=True;");
            configuration = new Configuration();
            configuration.Properties = properties;

            foreach (Assembly assembly in assemblies)
            {
                configuration = configuration.AddAssembly(assembly);
            }
            sessionFactory = configuration.BuildSessionFactory();

        }

        public ISession CreateSession()
        {
            ISession openSession = sessionFactory.OpenSession();
            IDbConnection connection = openSession.Connection;
            new SchemaExport(configuration).Execute(false, true, false, connection, null);
            return openSession;

        }
    } 
}
